﻿#region Creditos

/* Autor: Edilberto Sánchez Forero	*/
/* Email: esanchezfo@gmail.com		*/
/* Licencia: LGPL, Software Libre	*/
/* País: Colombia, Bogotá			*/

#endregion

#region Librerias

using System.Collections.Generic;
using System.Net;
using Ciatel.ISO8583.Amex;
using Ciatel.ISO8583.Amex.Utilities;
using ESF.General;
using ESF.SSO.Core.Entities;
using ESF.SSO.Core.Entities.Exceptions;
using System;
using ESF.General.Entity;
using ESF.SSO.Core.Entities.BasicReferences;
using System.Text;
using System.ServiceModel;
using System.Net.Sockets;

#endregion


namespace ESF.SSO.ISO8583.ServerRequestHandler.Operations
{
	internal static class SignIn_I
	{
		internal static void ProcessRequest (List<Message> pRequests, IPEndPoint pSenderIPEndPoint, IPEndPoint pForwarderIPEndPoint, out List<Message> pResponses, out List<object> pProcessedObjects)
		{
			User user;
			
			List<UserMenuItem> userMenus;
			
			Message response;
			
			Message request;
			
			CustomField customField_57;
			
			int menuIndex;
			int parteIndex;
			int index;
			
			StringBuilder stbRootMenuCodes;
			
			
			request = pRequests [0];
			
			request.ApplicationData.DataElements.CheckHasMandatoryFields
			(
				TheKnownFields.PrimaryAccountNumber, 
				TheKnownFields.PersonalIdentificationNumberData,
				TheKnownFields.CustomPrivateField_57
			);
			
			customField_57 = request.ApplicationData.DataElements.GetCustomPrivateField_57 ();
			
			pResponses = new List<Message> ();
			
			try
			{
				user = new User ()
				{
					IdentificationNumber = Tools.IntArrayToString (request.ApplicationData.DataElements.GetPrimaryAccountNumber ()).Replace (SSORequestHandler.Client_BIN, string.Empty),
					IdentificationType = new BasicReference () { ID = 1 },
					Password = request.ApplicationData.DataElements.GetPersonalIdentificationNumberDataAsString (SSORequestHandler.PASSWORD_LENGTH),
					UserTerminal = new Terminal () { Code = request.ApplicationData.DataElements.GetTerminalId (), UserHostAddress = pSenderIPEndPoint.ToString () }
				};
			
				using (SSOServiceClient.SSOServiceClient ssoClient = new SSOServiceClient.SSOServiceClient ())
				{
					user =  ssoClient.SignInByIdentificationCredentials (user);
					
					userMenus = ssoClient.GetUserMenu (user, new BasicReference () { Code = customField_57.GetStringFieldWithVariableLength (60) }); // Ans .. 60
				}
			
				#region Primera Respuesta
				
				response = request.GenerateBasicResponse (pForwarderIPEndPoint.Port);
				
				customField_57 = new CustomField ();

				customField_57.AddFieldWithVariableLength (user.SessionID, 40);				// Ans .. 40
				
				customField_57.AddFieldWithVariableLength (user.UserTerminal.Location.Name, 60);	// Ans .. 60
				customField_57.AddFieldWithVariableLength (user.UserTerminal.Location.Address, 60);	// Ans .. 60
				
				if (user.Enterprise != null)
				{
					customField_57.AddFieldWithVariableLength (user.Enterprise.NIT, 60);	// Ans .. 60	
					customField_57.AddFieldWithVariableLength (user.Enterprise.Name, 60);	// Ans .. 60	
				}
				else
				{
					customField_57.AddFieldWithVariableLength (string.Empty, 60);	// Ans .. 60	
					customField_57.AddFieldWithVariableLength (string.Empty, 60);	// Ans .. 60	
				}
				
				customField_57.AddFieldWithVariableLength (
					TextHelper.Concatenate (" ", user.FirstName, user.SecondName, user.SurName, user.LastName), 120);	// Ans .. 120
				
				stbRootMenuCodes = new StringBuilder ();
								
				if (userMenus != null && userMenus.Count > 0)
				{
					foreach (UserMenuItem mi in userMenus.FindAll (mix => mix.Parent == null))
					{
						// Se supone una longitud fija de los codigos
						stbRootMenuCodes.Append (mi.Code);
					}
				
					// userMenus.RemoveAll (mix => mix.ParentMenuItemID == null || mix.ParentMenuItemID == 0);
				}
				
				customField_57.AddFieldWithVariableLength (stbRootMenuCodes.ToString (), 20);		// Ans .. 20
				
				// Total Elementos del Menu
				if (userMenus != null && userMenus.Count > 0)
				{
					customField_57.AddField (userMenus.Count, 4);	// N 4
				}
				else
				{
					customField_57.AddField (0, 4);	// N 4
				}
				
				customField_57.Close ();
				
				response.ApplicationData.DataElements.SetCustomPrivateField_57 (customField_57);
				
				pResponses.Add (response);
				
				#endregion
				
				#region Menus
				
				if (userMenus != null && userMenus.Count > 0)
				{
					// Indice de pagina arranca en 1, se envian solo los hijos
					for (menuIndex = 0, index = 1; menuIndex < userMenus.Count; index ++)
					{
						response = request.GenerateBasicResponse (pForwarderIPEndPoint.Port);
						customField_57 = new CustomField ();
						
						customField_57.AddFieldWithVariableLength (user.SessionID, 40);				// Ans .. 40
						customField_57.AddField (index, 4);		// N 4
					
						for (parteIndex = 0; parteIndex < 12 && menuIndex < userMenus.Count; parteIndex ++, menuIndex ++)
						{
							customField_57.AddFieldWithVariableLength (userMenus [menuIndex].Code, 30);	// Ans .. 60
							
							if (userMenus [menuIndex].Parent != null)
							{
								customField_57.AddFieldWithVariableLength (userMenus [menuIndex].Parent.Code, 60);	// Ans .. 30
							}
							else
							{
								customField_57.AddFieldWithVariableLength (string.Empty, 60);	// Ans .. 60
							}
							
							customField_57.AddFieldWithVariableLength (userMenus [menuIndex].Name, 60);	// Ans .. 60
							customField_57.AddFieldWithVariableLength (userMenus [menuIndex].Description, 60);	// Ans .. 60
							customField_57.AddFieldWithVariableLength (userMenus [menuIndex].Extra_I, 60);	// Ans .. 60
							customField_57.AddFieldWithVariableLength (userMenus [menuIndex].Extra_II, 60);	// Ans .. 60
						}
						
						response.ApplicationData.DataElements.SetCustomPrivateField_57 (customField_57);
						pResponses.Add (response);
					}
				}				
				
				#endregion
				
				pProcessedObjects = new List<object> ();
				
				pProcessedObjects.Add (user);
				pProcessedObjects.Add (userMenus);
			}
			catch (FaultException gEx)
			{
				throw new GenericException (SSOExceptionCodes.ToSSOISO8583ExceptionCode (gEx.Code.Name), gEx.Message);
			}
		}
	}
}
